const KoaRouter = require('koa-router');

class NameSapce {
  /**
   * @param {string} namespace 命名空间
   * @param {KoaRouter} router koa-router
   */
  constructor (namespace, router) {
    this.namespace = namespace;
    this.router = router;
  }

  /**
   * @param {string} routerPath 
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  get(routerPath, ...middlewareOrController) {
    this.router.get(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  post(routerPath, ...middlewareOrController) {
    this.router.post(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  put(routerPath, ...middlewareOrController) {
    this.router.put(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  patch(routerPath, ...middlewareOrController) {
    this.router.patch(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  delete(routerPath, ...middlewareOrController) {
    this.router.delete(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 路由
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  link(routerPath, ...middlewareOrController) {
    return this.router.link(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 路由
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  unlink(routerPath, ...middlewareOrController) {
    return this.router.unlink(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 路由
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  head(routerPath, ...middlewareOrController) {
    return this.router.head(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 路由
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  options(routerPath, ...middlewareOrController) {
    return this.router.options(this.namespace + routerPath, ...middlewareOrController);
  }

  /**
   * @param {string} routerPath 路由
   * @param {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewareOrController 中间件或controller
   */
  all(routerPath, ...middlewareOrController) {
    return this.router.all(this.namespace + routerPath, ...middlewareOrController);
  }
}

module.exports = class Router extends KoaRouter{
  /**
   * 定义命名空间
   * @param {string} name 命名空间
   * @param  {Array<KoaRouter.IMiddleware<StateT, CustomT>>} middlewares 中间件列表
   */
  namespace(name, ...middlewares) {
    this.use(name, ...middlewares);
    return new NameSapce(name, this);
  }
};